package com.haoe.util.fastjson;

import com.alibaba.fastjson.JSON;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.junit.Test;

/**
 * @Author: 80305082
 * @Date: 2021/4/25
 * @Description: fastjson 解析复杂嵌套json字符串 实例
 * fastjson API 入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成。
 * ===================================================================================================================》》》
 * = public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray
 * = public static final JSONObject parseObject(String text)； // 把JSON文本parse成JSONObject
 * = public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean
 * = public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray
 * = public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合
 * = public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本
 * = public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本
 * = public static final Object toJSON(Object javaObject); //将JavaBean转换为JSONObject或者JSONArray。
 * 《《《============================================================================================================
 * <p>
 * 有关类库的一些说明
 * JSONArray : 相当于List
 * JSONObject: 相当于Map<String,Object>
 * <p>
 * JSON串：
 * [
 * {
 * "id": "user_list",
 * "key": "id",
 * "tableName": "用户列表",
 * "className": "cn.dmego.domain.User",
 * "column": [
 * {
 * "key": "rowIndex",
 * "header": "序号",
 * "width": "50",
 * "allowSort": "false"
 * },
 * {
 * "key": "id",
 * "header": "id",
 * "hidden": "true"
 * },
 * {
 * "key": "name",
 * "header": "姓名",
 * "width": "100",
 * "allowSort": "true"
 * }
 * ]
 * },
 * {
 * "id": "role_list",
 * "key": "id",
 * "tableName": "角色列表",
 * "className": "cn.dmego.domain.Role",
 * "column": [
 * {
 * "key": "rowIndex",
 * "header": "序号",
 * "width": "50",
 * "allowSort": "false"
 * },
 * {
 * "key": "id",
 * "header": "id",
 * "hidden": "true"
 * },
 * {
 * "key": "name",
 * "header": "名称",
 * "width": "100",
 * "allowSort": "true"
 * }
 * ]
 * }
 * ]
 * <p>
 * 思路：
 * 要想解析这种复杂的字符串，首先得先定义好与之相符的java POJO 对象，
 * 经过观察，我们发现，这个是一个json对象数组，每一个对象里包含了许多属性，其中还有一个属性的类型也是对象数组。
 * 所有，我们从里到外，先定义最里面的对象：
 */
public class FastJsonExample {


    @Test
    public void test() throws Exception {

    }

    public static void main(String[] args) {
        FastJsonExample example = new FastJsonExample();
        List<Query> objs = example.getObjs();
        System.out.println(objs);
    }

    /**
     * 读取类路径下的配置文件
     * 解析成对象数组并返回
     *
     * @throws IOException
     */
    public List<Query> getObjs() {
        // 读取类路径下的query.json文件
        //ClassLoader cl = this.getClass().getClassLoader();
        //InputStream inputStream = cl.getResourceAsStream("query.json");
        //String jsontext = IOUtils.toString(inputStream, "utf8");
        String jsontext = readJsonFile("src\\main\\java\\com\\haoe\\query.json");
        // 先将json字符串转为List数组
        List<Query> queryList = JSON.parseArray(jsontext, Query.class);
        for (Query query : queryList) {
            List<Column> columnList = new ArrayList<>();
            List<LinkedHashMap<String, Object>> columns = query.getColumn();
            for (LinkedHashMap<String, Object> LinkedHashMap : columns) {
                //将map转化为java实体类
                Column column = (Column) map2Object(LinkedHashMap, Column.class);
                System.out.println(column.toString());
                columnList.add(column);
            }
            query.setColumnList(columnList); //为columnList属性赋值
        }
        return queryList;
    }

    /**
     * 利用反射将Map转成实体对象
     *
     * @param map   map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    private Object map2Object(LinkedHashMap<String, Object> map, Class<Column> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                String flag = (String) map.get(field.getName());
                if (flag != null) {
                    //if (flag.equals("false") || flag.equals("true")) {
                    //    field.set(obj, Boolean.parseBoolean(flag));
                    //} else {
                    field.set(obj, map.get(field.getName()));
                    //}
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 读取json文件
     */
    public static String readJsonFile(String fileName) {
        String jsonStr = "";
        try {
            // 相对的是工作目录的路径：src
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
